package com.lagou.edu.service.impl;

import cn.hutool.core.util.IdUtil;
import com.lagou.edu.dao.UserDao;
import com.lagou.edu.pojo.User;
import com.lagou.edu.service.UserService;
import com.lagou.edu.util.JwtUtils;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.commons.util.IdUtils;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Objects;

@Service
@Slf4j
public class UserServiceImpl implements UserService {

    private static final String USER_REGISTER_CODE = "USER:REGISTER:CODE";

    @Autowired
    RedisTemplate redisTemplate;
    @Autowired
    UserDao userDao;

    // 0 注册成功  1 验证码输入错误   2 验证码已过期
    @Override
    public Integer register(String email, String password, String code) {
        if (StringUtils.isEmpty(email) || StringUtils.isEmpty(password) || StringUtils.isEmpty(code)) {
            throw new RuntimeException("注册的相关信息不能为空");
        }
        //根据email和code校验验证码是否过期和正确性
        String codeFromRedis = (String) redisTemplate.opsForHash().get(USER_REGISTER_CODE, email);
        if (StringUtils.isEmpty(codeFromRedis)){
            //说明该验证码已过期
            return 2;
        }
        if (!Objects.equals(codeFromRedis,code)){
            return 1;
        }
        //验证码正确且未过期，将用户信息保存
        User user = new User();
        user.setId(IdUtil.fastSimpleUUID());
        user.setEmail(email);
        user.setPassword(password);
        userDao.insertOneUser(user);
        return 0;
    }


    @Override
    public String getEmailByJwt(String jwtToken) throws Exception {
        if (StringUtils.isEmpty(jwtToken)) {
            throw new RuntimeException("token不能为空");
        }
        Claims claims = JwtUtils.parseJwt(jwtToken);
        if (JwtUtils.isTokenExpired(claims)) {
            //todo token过期，清空cookie的数据
            throw new RuntimeException("token不能为空,请重新登录");
        }
        String subject = claims.getSubject();
        log.info("email：{}", subject);
        return claims.getSubject();
    }

    @Override
    public Boolean login(HttpServletRequest request, HttpServletResponse response, String email, String password) throws Exception {
        if (StringUtils.isEmpty(email) || StringUtils.isEmpty(password)) {
            throw new RuntimeException("账号或密码不能为空");
        }
        Cookie[] cookies = request.getCookies();
        if (null != cookies) {
            for (Cookie cookie : cookies) {
                if (Objects.equals(cookie.getName(), "email")) {
                    String jwtFromCookie = cookie.getValue();
                    //解析jwt
                    Claims claims = JwtUtils.parseJwt(jwtFromCookie);
                    //判断jwt是否过期
                    if (JwtUtils.isTokenExpired(claims)) {
                        //token过期，清空cookie的数据
                        cookie.setMaxAge(0);
                        cookie.setPath("/");
                        response.addCookie(cookie);
                        //重定向到登录界面
                        log.info("当前用户重定向到登录页");
                        return false;
                    }
                    //获取用户的邮箱,id
                    String subject = claims.getSubject();
                    String userId = claims.getId();
                    //根据用户id获取用户信息
                    User userById = userDao.getUserById(userId);
                    if (Objects.equals(userById.getEmail(), subject)) {
                        log.info("当前用户：{}未经过登录页登陆成功", email);
                        return true;
                    } else {
                        log.info("当前用户：{}未经过登录页登陆失败，重定向到登录页", email);
                    }
                }
            }
        }
        User oneUser = userDao.getOneUser(email, password);
        if (null == oneUser) {
            throw new RuntimeException("账号或密码错误");
        }
        log.info("当前用户的邮箱：{}，密码：{}", email, password);
        //用户账号密码正确，根据<⽤户邮箱+密码> ⽣成签发token令牌，失效时间为10分钟，并保存到cookie中
        String jwt = JwtUtils.createJWT(String.valueOf(oneUser.getId()), email, 10 * 60 * 1000);
        Cookie cookie = new Cookie("email", jwt);
        cookie.setPath("/");
        response.addCookie(cookie);
        System.out.println(response.getHeaderNames());
//        log.info("当前用户的cookie为:{}:{}", cookie.getName(), cookie.getValue());
        log.info("当前用户：{}在登录页登陆成功", oneUser);
        return true;
    }


}
